<!-- 语义检索日志组件 - 自然语言查询解析过程回放 -->
<template>
  <div class="semantic-search-log">
    <div class="log-header">
      <h3 class="section-title">
        <el-icon><Document /></el-icon>
        语义检索日志
      </h3>
      <div class="header-actions">
        <el-button-group size="small">
          <el-button @click="clearLogs">
            <el-icon><Delete /></el-icon>
            清空日志
          </el-button>
          <el-button @click="exportLogs">
            <el-icon><Download /></el-icon>
            导出日志
          </el-button>
          <el-button type="primary" @click="startReplay">
            <el-icon><VideoPlay /></el-icon>
            过程回放
          </el-button>
        </el-button-group>
      </div>
    </div>

    <div class="log-content">
      <!-- 查询输入回放区 -->
      <div class="query-replay-section">
        <div class="section-header">
          <h4>查询解析回放</h4>
          <el-switch
            v-model="autoReplay"
            active-text="自动回放"
            inactive-text="手动控制"
            @change="toggleAutoReplay"
          ></el-switch>
        </div>
        
        <div class="query-analysis">
          <div class="original-query">
            <label>原始查询:</label>
            <div class="query-text">{{ currentQuery.original }}</div>
          </div>
          
          <div class="parsing-steps">
            <div
              v-for="(step, index) in parsingSteps"
              :key="index"
              class="parsing-step"
              :class="{ active: index <= currentParsingStep, completed: index < currentParsingStep }"
            >
              <div class="step-indicator">
                <div class="step-number">{{ index + 1 }}</div>
                <div class="step-line" v-if="index < parsingSteps.length - 1"></div>
              </div>
              <div class="step-content">
                <div class="step-title">{{ step.title }}</div>
                <div class="step-description">{{ step.description }}</div>
                <div class="step-result" v-if="step.result">
                  <el-tag
                    v-for="(token, tokenIndex) in step.result"
                    :key="tokenIndex"
                    :type="getTokenType(token.type)"
                    size="small"
                    class="token-tag"
                  >
                    {{ token.text }}
                  </el-tag>
                </div>
                <div class="step-time">{{ step.timestamp }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 搜索执行日志 -->
      <div class="execution-log-section">
        <div class="section-header">
          <h4>执行日志</h4>
          <el-select v-model="logLevel" size="small" @change="filterLogs">
            <el-option label="全部" value="all"></el-option>
            <el-option label="信息" value="info"></el-option>
            <el-option label="警告" value="warning"></el-option>
            <el-option label="错误" value="error"></el-option>
          </el-select>
        </div>
        
        <div class="log-list">
          <div
            v-for="(log, index) in filteredLogs"
            :key="index"
            class="log-entry"
            :class="log.level"
          >
            <div class="log-time">{{ log.timestamp }}</div>
            <div class="log-level">
              <el-tag :type="getLogLevelType(log.level)" size="small">
                {{ log.level.toUpperCase() }}
              </el-tag>
            </div>
            <div class="log-message">{{ log.message }}</div>
            <div class="log-details" v-if="log.details">
              <el-button link size="small" @click="toggleDetails(index)">
                <el-icon><View /></el-icon>
                {{ log.showDetails ? '收起' : '详情' }}
              </el-button>
              <div v-if="log.showDetails" class="details-content">
                <pre>{{ JSON.stringify(log.details, null, 2) }}</pre>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 性能指标 -->
      <div class="performance-metrics">
        <div class="section-header">
          <h4>性能指标</h4>
        </div>
        
        <div class="metrics-grid">
          <div class="metric-card">
            <div class="metric-label">解析耗时</div>
            <div class="metric-value">{{ performanceMetrics.parsingTime }}ms</div>
            <div class="metric-chart">
              <div
                class="chart-bar"
                :style="{ width: getPercentage(performanceMetrics.parsingTime, 100) + '%' }"
              ></div>
            </div>
          </div>
          
          <div class="metric-card">
            <div class="metric-label">索引查找</div>
            <div class="metric-value">{{ performanceMetrics.indexTime }}ms</div>
            <div class="metric-chart">
              <div
                class="chart-bar"
                :style="{ width: getPercentage(performanceMetrics.indexTime, 500) + '%' }"
              ></div>
            </div>
          </div>
          
          <div class="metric-card">
            <div class="metric-label">结果排序</div>
            <div class="metric-value">{{ performanceMetrics.sortingTime }}ms</div>
            <div class="metric-chart">
              <div
                class="chart-bar"
                :style="{ width: getPercentage(performanceMetrics.sortingTime, 200) + '%' }"
              ></div>
            </div>
          </div>
          
          <div class="metric-card">
            <div class="metric-label">总耗时</div>
            <div class="metric-value">{{ performanceMetrics.totalTime }}ms</div>
            <div class="metric-chart">
              <div
                class="chart-bar"
                :style="{ width: getPercentage(performanceMetrics.totalTime, 1000) + '%' }"
              ></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 回放控制器 -->
    <div class="replay-controls" v-if="isReplaying">
      <div class="controls-wrapper">
        <el-button-group>
          <el-button @click="pauseReplay">
            <el-icon><VideoPause /></el-icon>
          </el-button>
          <el-button @click="resumeReplay">
            <el-icon><VideoPlay /></el-icon>
          </el-button>
          <el-button @click="stopReplay">
            <el-icon><VideoClose /></el-icon>
          </el-button>
        </el-button-group>
        
        <div class="progress-section">
          <span class="progress-label">回放进度:</span>
          <el-slider
            v-model="replayProgress"
            :max="100"
            @change="seekReplay"
            class="progress-slider"
          ></el-slider>
        </div>
        
        <div class="speed-control">
          <span class="speed-label">速度:</span>
          <el-select v-model="replaySpeed" size="small" @change="changeReplaySpeed">
            <el-option label="0.5x" value="0.5"></el-option>
            <el-option label="1x" value="1"></el-option>
            <el-option label="2x" value="2"></el-option>
            <el-option label="4x" value="4"></el-option>
          </el-select>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { ElMessage } from 'element-plus'

// 响应式数据
const autoReplay = ref(true)
const logLevel = ref('all')
const currentParsingStep = ref(-1)
const isReplaying = ref(false)
const replayProgress = ref(0)
const replaySpeed = ref(1)

// 当前查询数据
const currentQuery = ref({
  original: '查找北京地区频率在1200-1800MHz之间的雷达信号，威胁级别高于3级',
  parsed: {}
})

// 解析步骤
const parsingSteps = ref([
  {
    title: '自然语言预处理',
    description: '对输入文本进行分词、去停用词等预处理',
    result: [
      { text: '查找', type: 'action' },
      { text: '北京地区', type: 'location' },
      { text: '频率', type: 'parameter' },
      { text: '1200-1800MHz', type: 'range' },
      { text: '雷达信号', type: 'signal_type' },
      { text: '威胁级别', type: 'parameter' },
      { text: '高于3级', type: 'condition' }
    ],
    timestamp: '2024-01-15 14:30:01.123'
  },
  {
    title: '语义实体识别',
    description: '识别查询中的实体和关系',
    result: [
      { text: 'LOCATION: 北京', type: 'entity' },
      { text: 'FREQUENCY: 1200-1800MHz', type: 'entity' },
      { text: 'SIGNAL_TYPE: 雷达', type: 'entity' },
      { text: 'THREAT_LEVEL: >3', type: 'entity' }
    ],
    timestamp: '2024-01-15 14:30:01.156'
  },
  {
    title: '查询意图分析',
    description: '分析用户的搜索意图和目标',
    result: [
      { text: '搜索类型: 条件检索', type: 'intent' },
      { text: '返回格式: 信号列表', type: 'intent' },
      { text: '排序方式: 威胁级别', type: 'intent' }
    ],
    timestamp: '2024-01-15 14:30:01.189'
  },
  {
    title: '查询语句生成',
    description: '将语义理解结果转换为数据库查询',
    result: [
      { text: 'SELECT * FROM signals', type: 'sql' },
      { text: 'WHERE location = "北京"', type: 'sql' },
      { text: 'AND frequency BETWEEN 1200 AND 1800', type: 'sql' },
      { text: 'AND type = "雷达"', type: 'sql' },
      { text: 'AND threat_level > 3', type: 'sql' }
    ],
    timestamp: '2024-01-15 14:30:01.234'
  }
])

// 执行日志
const executionLogs = ref([
  {
    timestamp: '2024-01-15 14:30:01.245',
    level: 'info',
    message: '开始执行语义检索查询',
    details: { queryId: 'q_001', userId: 'user_123' },
    showDetails: false
  },
  {
    timestamp: '2024-01-15 14:30:01.267',
    level: 'info',
    message: '索引查找完成，找到1247条候选记录',
    details: { indexType: 'frequency_index', candidateCount: 1247 },
    showDetails: false
  },
  {
    timestamp: '2024-01-15 14:30:01.298',
    level: 'warning',
    message: '部分记录缺少威胁级别信息，使用默认值',
    details: { missingCount: 23, defaultValue: 1 },
    showDetails: false
  },
  {
    timestamp: '2024-01-15 14:30:01.334',
    level: 'info',
    message: '应用地理位置过滤器',
    details: { bounds: { north: 40.5, south: 39.4, east: 117.0, west: 115.5 } },
    showDetails: false
  },
  {
    timestamp: '2024-01-15 14:30:01.378',
    level: 'info',
    message: '检索完成，返回156条匹配结果',
    details: { resultCount: 156, totalTime: 133 },
    showDetails: false
  }
])

// 性能指标
const performanceMetrics = ref({
  parsingTime: 45,
  indexTime: 156,
  sortingTime: 23,
  totalTime: 224
})

// 计算过滤后的日志
const filteredLogs = computed(() => {
  if (logLevel.value === 'all') {
    return executionLogs.value
  }
  return executionLogs.value.filter(log => log.level === logLevel.value)
})

// 获取Token类型样式
const getTokenType = (type) => {
  const typeMap = {
    'action': 'primary',
    'location': 'success',
    'parameter': 'info',
    'range': 'warning',
    'signal_type': 'danger',
    'condition': 'warning',
    'entity': 'success',
    'intent': 'primary',
    'sql': 'info'
  }
  return typeMap[type] || ''
}

// 获取日志级别类型
const getLogLevelType = (level) => {
  const levelMap = {
    'info': 'primary',
    'warning': 'warning',
    'error': 'danger'
  }
  return levelMap[level] || 'info'
}

// 获取百分比
const getPercentage = (value, max) => {
  return Math.min((value / max) * 100, 100)
}

// 清空日志
const clearLogs = () => {
  executionLogs.value = []
  ElMessage.success('日志已清空')
}

// 导出日志
const exportLogs = () => {
  const logData = {
    query: currentQuery.value,
    parsingSteps: parsingSteps.value,
    executionLogs: executionLogs.value,
    performance: performanceMetrics.value
  }
  
  const blob = new Blob([JSON.stringify(logData, null, 2)], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `semantic-search-log-${Date.now()}.json`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
  
  ElMessage.success('日志已导出')
}

// 开始回放
const startReplay = () => {
  isReplaying.value = true
  currentParsingStep.value = -1
  replayProgress.value = 0
  
  if (autoReplay.value) {
    runAutoReplay()
  }
  
  ElMessage.success('开始解析过程回放')
}

// 自动回放
const runAutoReplay = () => {
  const totalSteps = parsingSteps.value.length
  const stepDuration = 2000 / replaySpeed.value // 基础间隔2秒
  
  const playNextStep = () => {
    if (currentParsingStep.value < totalSteps - 1 && isReplaying.value) {
      currentParsingStep.value++
      replayProgress.value = ((currentParsingStep.value + 1) / totalSteps) * 100
      
      setTimeout(playNextStep, stepDuration)
    } else {
      isReplaying.value = false
      ElMessage.success('回放完成')
    }
  }
  
  setTimeout(playNextStep, stepDuration)
}

// 暂停回放
const pauseReplay = () => {
  isReplaying.value = false
  ElMessage.info('回放已暂停')
}

// 恢复回放
const resumeReplay = () => {
  isReplaying.value = true
  if (autoReplay.value) {
    runAutoReplay()
  }
  ElMessage.info('回放已恢复')
}

// 停止回放
const stopReplay = () => {
  isReplaying.value = false
  currentParsingStep.value = -1
  replayProgress.value = 0
  ElMessage.info('回放已停止')
}

// 跳转回放
const seekReplay = (progress) => {
  const totalSteps = parsingSteps.value.length
  currentParsingStep.value = Math.floor((progress / 100) * totalSteps) - 1
}

// 改变回放速度
const changeReplaySpeed = (speed) => {
  // 速度改变时重新计算间隔
}

// 切换自动回放
const toggleAutoReplay = (auto) => {
  if (auto && isReplaying.value) {
    runAutoReplay()
  }
}

// 过滤日志
const filterLogs = () => {
  // 日志过滤逻辑由computed处理
}

// 切换详情显示
const toggleDetails = (index) => {
  executionLogs.value[index].showDetails = !executionLogs.value[index].showDetails
}

// 组件挂载
onMounted(() => {
  // 初始化操作
})
</script>

<style scoped>
.semantic-search-log {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 1vh;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  overflow: visible;
  flex-shrink: 0;
  min-width: 0;
}

.log-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2vh 3vw;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.section-title {
  color: #ffffff;
  font-size: 1.8rem;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 1vw;
}

.log-content {
  flex: 1;
  padding: 1.5vh 1vw;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1.5vh;
  width: 100%;
  min-height: 0;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1vh;
  padding-bottom: 0.5vh;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.section-header h4 {
  color: #ffffff;
  margin: 0;
  font-size: 1rem;
}

.query-replay-section {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 0.8vh;
  padding: 1.5vh 1vw;
  flex: 0 0 auto;
  height: auto;
  overflow: visible;
}

.original-query {
  margin-bottom: 1.5vh;
}

.original-query label {
  color: #bdc3c7;
  font-size: 0.9rem;
  display: block;
  margin-bottom: 1vh;
}

.query-text {
  background: rgba(255, 255, 255, 0.1);
  color: #ffffff;
  padding: 1.5vh 2vw;
  border-radius: 0.5vh;
  font-family: monospace;
  border-left: 0.3vw solid #4a90e2;
}

.parsing-steps {
  position: relative;
}

.parsing-step {
  display: flex;
  margin-bottom: 1.5vh;
  opacity: 0.5;
  transition: all 0.3s ease;
}

.parsing-step.active {
  opacity: 1;
  transform: scale(1.02);
}

.parsing-step.completed {
  opacity: 0.8;
}

.step-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-right: 0.8vw;
}

.step-number {
  width: 3vh;
  height: 3vh;
  border-radius: 50%;
  background: #4a90e2;
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 0.8rem;
  z-index: 1;
}

.step-line {
  width: 0.2vw;
  height: 2vh;
  background: rgba(255, 255, 255, 0.2);
  margin-top: 0.5vh;
}

.step-content {
  flex: 1;
  padding: 1vh 0;
}

.step-title {
  color: #ffffff;
  font-weight: 500;
  font-size: 1.1rem;
  margin-bottom: 1vh;
}

.step-description {
  color: #bdc3c7;
  font-size: 0.9rem;
  margin-bottom: 1.5vh;
}

.step-result {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5vw;
  margin-bottom: 0.8vh;
}

.token-tag {
  font-family: monospace;
  font-size: 0.7rem;
  padding: 0.2vh 0.5vw;
}

.step-time {
  color: #95a5a6;
  font-size: 0.8rem;
  font-family: monospace;
}

.execution-log-section {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 0.8vh;
  padding: 1.5vh 1vw;
  flex: 1;
  min-height: 25vh;
  overflow: visible;
  display: flex;
  flex-direction: column;
}

.log-list {
  flex: 1;
  overflow-y: auto;
  max-height: none;
}

.log-entry {
  display: flex;
  align-items: flex-start;
  gap: 1vw;
  padding: 1vh 1vw;
  margin-bottom: 0.8vh;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 0.5vh;
  border-left: 0.2vw solid #4a90e2;
}

.log-entry.warning {
  border-left-color: #f39c12;
}

.log-entry.error {
  border-left-color: #e74c3c;
}

.log-time {
  color: #95a5a6;
  font-size: 0.8rem;
  font-family: monospace;
  min-width: 12vw;
}

.log-level {
  min-width: 6vw;
}

.log-message {
  flex: 1;
  color: #ffffff;
  font-size: 0.9rem;
}

.log-details {
  min-width: 8vw;
}

.details-content {
  margin-top: 1vh;
  background: rgba(0, 0, 0, 0.5);
  padding: 1vh;
  border-radius: 0.3vh;
  font-size: 0.8rem;
}

.details-content pre {
  color: #ffffff;
  margin: 0;
  white-space: pre-wrap;
  font-family: monospace;
}

.performance-metrics {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 0.8vh;
  padding: 1.5vh 1vw;
  flex: 0 0 auto;
  height: auto;
}

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1vw;
}

.metric-card {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 0.6vh;
  padding: 1.5vh;
  text-align: center;
  min-height: 8vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.metric-label {
  color: #bdc3c7;
  font-size: 0.8rem;
  margin-bottom: 0.5vh;
}

.metric-value {
  color: #ffffff;
  font-size: 1.1rem;
  font-weight: bold;
  margin-bottom: 0.8vh;
}

.metric-chart {
  height: 0.8vh;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 0.4vh;
  overflow: hidden;
}

.chart-bar {
  height: 100%;
  background: linear-gradient(90deg, #4a90e2, #74b9ff);
  border-radius: 0.4vh;
  transition: width 0.3s ease;
}

.replay-controls {
  background: rgba(0, 0, 0, 0.7);
  padding: 1vh 1vw;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  flex: 0 0 auto;
}

.controls-wrapper {
  display: flex;
  align-items: center;
  gap: 1.5vw;
  flex-wrap: wrap;
}

.progress-section {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 1vw;
}

.progress-label {
  color: #ffffff;
  font-size: 0.9rem;
  min-width: 6vw;
}

.progress-slider {
  flex: 1;
}

.speed-control {
  display: flex;
  align-items: center;
  gap: 1vw;
}

.speed-label {
  color: #ffffff;
  font-size: 0.9rem;
  min-width: 4vw;
}

/* 深色主题滚动条 */
::-webkit-scrollbar {
  width: 0.5vw;
}

::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 0.25vw;
}

::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.3);
  border-radius: 0.25vw;
}

::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.5);
}
</style>